package com.zwps.biz.domain.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zwps.biz.api.model.dto.mointordentify.AlarmBroacdCastVO;
import com.zwps.biz.api.model.vo.elements.ReservoirInundationVO;
import com.zwps.biz.api.model.vo.elements.SectionDownstreamVO;
import com.zwps.biz.api.model.vo.fourpipes.ZForeManageSafeDateVO;
import com.zwps.biz.api.model.vo.pubpointall.*;
import com.zwps.biz.api.model.vo.pubwarnrec.CrossSectionCodeVO;
import com.zwps.biz.api.model.vo.pubwarnrec.CrossSectionVO;
import com.zwps.biz.api.model.vo.structure.PubWarnVO;
import com.zwps.biz.api.model.vo.ststbprp.OtherPptnDateVO;
import com.zwps.biz.api.model.vo.ststbprp.OtherPptnPointDataVO;
import com.zwps.biz.api.model.vo.ststbprp.OtherPptnPointVO;
import com.zwps.biz.dal.db.dao.ElementsDAO;
import com.zwps.biz.dal.db.dao.PubPointAllDAO;
import com.zwps.biz.dal.db.object.PubPointAllDO;
import com.zwps.biz.domain.service.MonitorAlarmRecordIdentifyService;
import com.zwps.biz.domain.service.PubPointAllService;
import com.zwps.biz.domain.service.TDepartmentService;
import com.zwps.biz.domain.service.ZWaterLawEnforcementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class PubPointAllServiceImpl extends ServiceImpl<PubPointAllDAO, PubPointAllDO> implements PubPointAllService {
    @Autowired
    private PubPointAllDAO pubPointAllDAO;
    @Autowired
    private ElementsDAO elementsDAO;
    @Autowired
    TDepartmentService tDepartmentService;
    @Autowired
    private MonitorAlarmRecordIdentifyService service;
    @Autowired
    ZWaterLawEnforcementService waterLawEnforcementService;

    private static final BigDecimal THRESHOLD_100 = new BigDecimal("100.0");
    private static final BigDecimal THRESHOLD_50 = new BigDecimal("50.0");

    @Override
    public String getVideoURL(String rscd) {
        return pubPointAllDAO.getVideoURL(rscd);
    }

    @Override
    public List<PubPointAllVO> getAddress(String sttpcd) {

        List<PubPointAllVO> list = pubPointAllDAO.getAddress(sttpcd);
        if (null ==list || list.isEmpty() ) {
            sttpcd = "22";
            list = pubPointAllDAO.getAddress(sttpcd);
        }
        return list;

    }
    @Override
    public Map<String, Object> queryForcastRainLineChartData(String nowTimes, String accessToken) {
        Map<String, Object> dataMap = new HashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:10:00");
        SimpleDateFormat sdff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<String> xdata = new ArrayList<>();//时间
        List<Map<String, Object>> sdata = new ArrayList<>();//数据
        Map<String, Object> waterMap = new HashMap<>();
        Map<String, Object> flowMap = new HashMap<>();
        List<String> waterData = new ArrayList<>();//水位
        List<String> flowData = new ArrayList<>();//流量
        try{
            List<Map<String, Object>>  list = pubPointAllDAO.queryNowWaterAndFlow();
            String tm = "";
            String rz = "0";
            String inq = "0";
            for(Map<String, Object> map : list){
                if(map.get("STCD")!=null){
                    String stcd = String.valueOf(map.get("STCD"));
                    if("62901300".equals(stcd)){
                        tm = String.valueOf(map.get("TM"));//时间
                        rz = String.valueOf(map.get("RZ"))=="null"?"0":String.valueOf(map.get("RZ"));//水位
                        inq = String.valueOf(map.get("INQ"))=="null"?"0":String.valueOf(map.get("INQ"));//入库流量
                    }
                }
            }
            //实时时间
            xdata.add(tm);
            waterData.add(rz);
            flowData.add(inq);
            if(StringUtils.isEmpty(nowTimes)){
                nowTimes = StringUtils.isEmpty(tm)?sdf.format(new Date()):sdf.format(sdff.parse(tm));
            }else{
                nowTimes = sdf.format(sdff.parse(nowTimes));
            }
//            Map<String,Object> formMap = new HashMap<>();
//            formMap.put("projectId","21d3fd35596542fa9215d8ba5a618b76");
//            formMap.put("bTime",nowTimes);
//            String result = HttpRequest.get(httpRequestConfig.getRsvrRainLineChartApi()).header("token",accessToken).form(formMap).execute().body();
//            JSONObject jsonObject = JSONObject.parseObject(result);
//            if(jsonObject!=null && jsonObject.size()>0){
//                String code = jsonObject.getString("state");
//                if("0".equals(code)){
//                    JSONObject object = jsonObject.getJSONObject("data");
//                    if(object!=null){
//                        JSONArray jsonArray = object.getJSONArray("001");
//                        int num = jsonArray.size();
//                        if(jsonArray!=null && num>0){
//                            for (int i=0;i<num;i++) {
//                                JSONObject obj = jsonArray.getJSONObject(i);
//                                String time = obj.getString("time");
//                                String upz = obj.getString("upz");//水位
//                                String ruku = obj.getString("inq");//入库流量
//                                String chuku = obj.getString("outq");//出库流量
//                                //预报时间
//                                xdata.add(time);
//                                waterData.add(upz);
//                                flowData.add(ruku);
//                            }
//                        }
//                    }
//                }else{
//                    dataMap.put("message",jsonObject);
//                }
//            }
        }catch (Exception e){
            e.printStackTrace();
            dataMap.put("message",e.getMessage());
        }
        waterMap.put("name","预报水位");
        flowMap.put("name","预报流量");
        waterMap.put("waterData",waterData);
        flowMap.put("flowData",flowData);
        sdata.add(waterMap);
        sdata.add(flowMap);
        dataMap.put("xdata",xdata);
        dataMap.put("sdata",sdata);
        dataMap.put("nowTimes",nowTimes);
        return  dataMap;
    }

    @Override
    public MaintainInfoVO getMaintainInfo(Integer year, String projectType) {
        List<MaintainVO> maintainInfoVOList = pubPointAllDAO.getMaintainInfo(year, projectType);
        MaintainInfoVO maintainInfoVO = new MaintainInfoVO();
        Map<String, List<MaintainVO>> listMap = maintainInfoVOList.stream()
                .collect(Collectors.groupingBy(MaintainVO::getTableName, Collectors.toList()));
        List<MaintainVO> plan = listMap.getOrDefault("plan", Collections.emptyList());
        List<MaintainVO> project = listMap.getOrDefault("project", Collections.emptyList());
        List<MaintainVO> record = listMap.getOrDefault("record", Collections.emptyList());

        maintainInfoVO.setPlanNum(plan.size());
        maintainInfoVO.setContractNum(project.size());
        maintainInfoVO.setRecordNum(record.size());
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(projectType)) {
            switch (projectType) {
                case "1":
                    maintainInfoVO.setMaintainInfoVOList(project);
                    break;
                case "2":
                    maintainInfoVO.setMaintainInfoVOList(plan);
                    break;
                case "3":
                    maintainInfoVO.setMaintainInfoVOList(record);
                    break;
                default:
                    maintainInfoVO.setMaintainInfoVOList(Collections.emptyList());
                    break;
            }
        } else {
            maintainInfoVO.setMaintainInfoVOList(maintainInfoVOList);
        }
        BigDecimal totalProjMoney = BigDecimal.ZERO;
        for (MaintainVO infoVO : plan) {
            totalProjMoney = totalProjMoney.add(infoVO.getProjMoney());  // 使用 add 方法累加 BigDecimal
        }
        maintainInfoVO.setProjectMoney(
                project.stream()
                        .map(MaintainVO::getProjMoney)
                        .reduce(BigDecimal.ZERO, BigDecimal::add)
        );
        maintainInfoVO.setPersonnelSalary(tDepartmentService.getPay(year).getYearWages());
        maintainInfoVO.setYearMoney(totalProjMoney);
        return maintainInfoVO;
    }

    @Override
    public RsvrInfoVO getRsvrInfo() {
        RsvrInfoVO rsvrInfo = pubPointAllDAO.getRsvrInfo();
        rsvrInfo.setTtcp(rsvrInfo.getTtcp().multiply(new BigDecimal("100")));
        rsvrInfo.setFldcp(rsvrInfo.getFldcp().multiply(new BigDecimal("100")));
        rsvrInfo.setActcp(rsvrInfo.getActcp().multiply(new BigDecimal("100")));
        rsvrInfo.setDdcp(rsvrInfo.getDdcp().multiply(new BigDecimal("100")));
        //处理调洪库容对不上问题
        rsvrInfo.setFlstcp(rsvrInfo.getFlstcp().divide(new BigDecimal("100")));
        rsvrInfo.setSubVal(pubPointAllDAO.getFloodLimit());
        return rsvrInfo;
    }

    @Override
    public List<ArchivesVO> getArchives(String id) {
        List<ArchivesVO> archives = pubPointAllDAO.getArchives(id);
        List<ArchivesVO> getFile = pubPointAllDAO.getfile(id);
        if (!getFile.isEmpty()) {
            archives.addAll(getFile);
        }
        return archives;
    }

    @Override
    public List<PubPointAllVO> getPoinDate(Integer type) {
        if (type==13){
            return  pubPointAllDAO.getPoinDateList(type);
        }else {
            return pubPointAllDAO.getPoinDate(type);
        }
    }

    @Override
    public List<RzRationVO> getRzRation(Integer type) {
        return pubPointAllDAO.getRzRation(type);
    }

    @Override
    public NowDateNewVO getNowDateNew() {
        NowDateNewVO nowDateNew = pubPointAllDAO.getNowDateNew();
        List<PubSectionWarnVO> list = pubPointAllDAO.geDrpByType();
//        加权面雨量
//        nowDateNew.setDrp(getDrp(list));

        double average = list.stream()
                .mapToDouble(item ->Double.valueOf(item.getVals().toString()))
                .average()
                .orElse(0.0);

        nowDateNew.setDrp(BigDecimal.valueOf(average).setScale(2, RoundingMode.HALF_UP));
        if (nowDateNew == null) {
            nowDateNew = new NowDateNewVO();
        }
        return nowDateNew;
    }

    @Override
    public List<CrossSectionVO> getCrossSectionList(Integer sccd) {
        return pubPointAllDAO.getCrossSectionList(sccd);
    }

    @Override
    public List<CrossSectionCodeVO> getCrossSectionCode() {
        return pubPointAllDAO.getCrossSectionCode();
    }

    @Override
    public Object getWDate(String id) {
        if (StringUtils.isEmpty(id)|| "2020".equals(id)) {
            id="10";
        }
        ObjectMapper mapper = new ObjectMapper();
        try {
            if (pubPointAllDAO.getWDate(id)==null){
               return null;
            }else {
            Object json = mapper.readValue(pubPointAllDAO.getWDate(id), Object.class);
            return json;
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Failed to process JSON", e);
        }
    }

    @Override
    public List<PubPointCountVO> countPointByType(String type) {
        List<PubPointCountVO> list = new ArrayList<>();
        if (type != null) {
            list.add(pubPointAllDAO.countPointByType(type));
            return list;
        }
        List<PttnSectionVO> pointType = getPointType();
        PubPointCountVO pubPointCountAllVO = pubPointAllDAO.countPointByType(null);
        pubPointCountAllVO.setPointName("总数");
        list.add(pubPointCountAllVO);
        pointType.stream().forEach(item -> {
            PubPointCountVO pubPointCountVO = pubPointAllDAO.countPointByType(item.getPtcd());
            pubPointCountVO.setPointName(item.getName());
            list.add(pubPointCountVO);
        });

        return list;
    }

    @Override
    public JSONArray getSectionData(String id) {
        JSONObject evolution = pubPointAllDAO.getEvolutionData("2020".equals(id)?"10":id);
        if (evolution == null) {
            return new JSONArray();
        }

        JSONArray data = evolution.getJSONArray("data");
        JSONObject sectionData = evolution.getJSONObject("section_data");
        if (sectionData == null) {
            return new JSONArray();
        }

        List<SectionDownstreamVO> sectionDownstreamList = elementsDAO.getSectionDownstream();
        Map<Integer, SectionDownstreamVO> sectionDownstreamMap = sectionDownstreamList.stream()
                .collect(Collectors.toMap(SectionDownstreamVO::getId, Function.identity()));

        JSONArray sectionDataList = new JSONArray();
        for (Map.Entry<String, Object> sectionDatum : sectionData) {
            JSONObject section = (JSONObject) sectionDatum.getValue();
            if (sectionDownstreamMap.containsKey(section.getInt("section_id"))) {
                SectionDownstreamVO sectionDownstream = sectionDownstreamMap.get(section.getInt("section_id"));
                section.set("name", sectionDownstream.getName());
                section.set("lat", sectionDownstream.getLat());
                section.set("lon", sectionDownstream.getLon());
                section.set("gc", 0);
            }
            JSONArray time_series = section.getJSONArray("time_series");
            for (Object timeSery : time_series) {
                // 处理保留两位小数
                JSONObject series = (JSONObject) timeSery;
                series.set("avg_depth_m", series.getBigDecimal("avg_depth_m").setScale(2, RoundingMode.HALF_UP));
                series.set("wetted_area_m2", series.getBigDecimal("avg_depth_m").setScale(2, RoundingMode.HALF_UP));
                series.set("discharge_m3s", series.getBigDecimal("discharge_m3s").setScale(2, RoundingMode.HALF_UP));
                series.set("avg_velocity_ms", series.getBigDecimal("avg_velocity_ms").setScale(2, RoundingMode.HALF_UP));
            }
            //保持和演进结果数量一致复制最后一条数据
            if (data.size() > time_series.size()) {
                for (int i = 0; i < data.size() - time_series.size(); i++) {
                    JSONObject lastObj = new JSONObject(time_series.getJSONObject(time_series.size() - 1).toString());
                    lastObj.set("time_hr", time_series.size());
                    time_series.add(lastObj);
                }
            }
            section.set("time_series", time_series);
            sectionDataList.add(section);
        }
        return sectionDataList;
    }

    @Override
    public List<PubPointCountVO> countPointByTypes(String type) {
        List<String> typeList = Arrays.asList(type.split(","));
        List<PubPointCountVO> pointStats = pubPointAllDAO.countPointByTypes(typeList);
        Map<Integer, PubPointCountVO> pointMap = pointStats.stream()
                .collect(Collectors.toMap(PubPointCountVO::getSttpcd, Function.identity()));
        int totalCount = pointStats.stream().mapToInt(PubPointCountVO::getAllCount).sum();
        int totalOnline = pointStats.stream().mapToInt(PubPointCountVO::getNormalCount).sum();
        int totalOffline = pointStats.stream().mapToInt(PubPointCountVO::getAbnormalCount).sum();
        PubPointCountVO totalVO = new PubPointCountVO();
        totalVO.setPointName("总数");
        totalVO.setAllCount(totalCount);
        totalVO.setNormalCount(totalOnline);
        totalVO.setAbnormalCount(totalOffline);
        List<PubPointCountVO> resultList = new ArrayList<>();
        resultList.add(totalVO);
        for (Map.Entry<Integer, PubPointCountVO> entry : pointMap.entrySet()) {
            Integer sttpcd = entry.getKey();
            PubPointCountVO pointCount = entry.getValue();
            getAnomalyCountForPoint(sttpcd.toString(), pointCount);
            resultList.add(pointCount);
        }
        if (typeList.contains("0")){
            List<PubPointCountVO> list = service.countsDevice("1");
            resultList.addAll(list);
        }
        if (typeList.contains("99")){
            List<ZForeManageSafeDateVO> zForemanageSafeList = waterLawEnforcementService.getZForemanageSafeList("86,87,88,89", null);
            Map<Integer, List<ZForeManageSafeDateVO>> dataByType = zForemanageSafeList.stream()
                    .collect(Collectors.groupingBy(ZForeManageSafeDateVO::getType));
            PubPointCountVO vo = new PubPointCountVO();
            vo.setReportNum(dataByType.get(86).get(0).getList().size());
            vo.setPicNum(dataByType.get(88).get(0).getList().size());
            vo.setVedioNum(dataByType.get(87).get(0).getList().size());
            vo.setModelNum(dataByType.get(89).get(0).getList().size());
            vo.setSttpcd(99);
            vo.setPointName("无人机");
            resultList.add(vo);
        }

        return resultList;
    }
    private void getAnomalyCountForPoint(String type, PubPointCountVO pointCount) {
        String dtvaltb = pubPointAllDAO.getDtvaltbc(pointCount.getSttpcd());
        List<PubValVO> upLowThresholdByPtcds = pubPointAllDAO.getUpLowThresholdByPtcds(null);
        String valType = getValTypeMapping(type, dtvaltb);
        if (valType == null) pointCount.setAnomalyNum(0); ;

        Map<String, Object> params = buildParamMap(dtvaltb, valType, pointCount.getPtcd());
        if (pointCount.getSttpcd()==13){
            List<PubWarnVO> list=new ArrayList<>();
            Map<String, PubValVO> collect = upLowThresholdByPtcds.stream()
                    .collect(Collectors.toMap(PubValVO::getUnit, Function.identity()));
            int exDataNum = 0;
            List<PubRainSectionWarnVO> rainStutasByType = pubPointAllDAO.getRainStutasByType(params);
            for (PubRainSectionWarnVO pubRainSectionWarnVO : rainStutasByType) {
                ;
                if (pubRainSectionWarnVO.getRainfall3h() != null
                        && pubRainSectionWarnVO.getRainfall3h().compareTo(THRESHOLD_100) >= 0) {
                    PubWarnVO pubWarnVO = new PubWarnVO();
                    pubWarnVO.setWarnConment(pubRainSectionWarnVO.getStcd() + "的值："  + "过去3小时已经超出阈值：100mm" );
                    pubWarnVO.setStcd(pubRainSectionWarnVO.getStcd());
                    pubWarnVO.setTime(LocalDateTime.now().toString());

                    exDataNum++;
                    list.add(pubWarnVO);// 红色：3h ≥ 100mm
                } else if (pubRainSectionWarnVO.getRainfall3h() != null
                        && pubRainSectionWarnVO.getRainfall3h().compareTo(THRESHOLD_50) >= 0) {
                    PubWarnVO pubWarnVO = new PubWarnVO();
                    pubWarnVO.setWarnConment(pubRainSectionWarnVO.getStcd() + "的值："  + "过去3小时已经超出阈值：50mm" );
                    pubWarnVO.setStcd(pubRainSectionWarnVO.getStcd());
                    pubWarnVO.setTime(LocalDateTime.now().toString());
                    exDataNum++;   // 橙色：3h ≥ 50mm
                    list.add(pubWarnVO);
                } else if (pubRainSectionWarnVO.getRainfall6h() != null
                        && pubRainSectionWarnVO.getRainfall6h().compareTo(THRESHOLD_50) >= 0) {
                    PubWarnVO pubWarnVO = new PubWarnVO();
                    pubWarnVO.setWarnConment(pubRainSectionWarnVO.getStcd() + "的值："  + "过去6小时已经超出阈值：50mm" );
                    pubWarnVO.setStcd(pubRainSectionWarnVO.getStcd());
                    pubWarnVO.setTime(LocalDateTime.now().toString());
                    exDataNum++; // 黄色：6h ≥ 50mm
                    list.add(pubWarnVO);
                } else if (pubRainSectionWarnVO.getRainfall12h() != null
                        && pubRainSectionWarnVO.getRainfall12h().compareTo(THRESHOLD_50) >= 0) {
                    PubWarnVO pubWarnVO = new PubWarnVO();
                    pubWarnVO.setWarnConment(pubRainSectionWarnVO.getStcd() + "的值："  + "过去12小时已经超出阈值：50mm" );
                    pubWarnVO.setStcd(pubRainSectionWarnVO.getStcd());
                    pubWarnVO.setTime(LocalDateTime.now().toString());
                    exDataNum++;
                    list.add(pubWarnVO);// 蓝色：12h ≥ 50mm
                }
                pointCount.setWarnVOList(list);

            }
            pointCount.setAnomalyNum(exDataNum); ;
        }else if (pointCount.getSttpcd()==15){
            List<PubWarnVO> list=new ArrayList<>();
            int exDataNum = 0;
            Map<String, PubValVO> collect = upLowThresholdByPtcds.stream()
                    .collect(Collectors.toMap(PubValVO::getUnit, Function.identity()));
            List<PubSectionWarnVO> sectionList = pubPointAllDAO.getSectionStutasByType(params);
            for (PubSectionWarnVO warnVO : sectionList) {

                BigDecimal val = Optional.ofNullable(warnVO.getVals())
                        .map(Object::toString)
                        .map(BigDecimal::new)
                        .orElse(BigDecimal.ZERO);


                if (val.compareTo(new BigDecimal("138")) >= 0) {  // val >= 138
                    PubWarnVO pubWarnVO = new PubWarnVO();
                    pubWarnVO.setWarnConment(warnVO.getStcd() + "的值：" + val + "已经超出阈值：138" );
                    pubWarnVO.setStcd(warnVO.getStcd());
                    pubWarnVO.setTime(warnVO.getTime());
                    exDataNum++;
                    list.add(pubWarnVO);

                } else if (val.compareTo(new BigDecimal("128")) >= 0) {  // val >= 128
                    PubWarnVO pubWarnVO = new PubWarnVO();
                    pubWarnVO.setWarnConment(warnVO.getStcd() + "的值：" + val + "已经超出阈值：128" );
                    pubWarnVO.setStcd(warnVO.getStcd());
                    pubWarnVO.setTime(warnVO.getTime());
                    exDataNum++;
                    list.add(pubWarnVO);
                } else if (val.compareTo(new BigDecimal("74")) >= 0) {  // val >= 74
                    PubWarnVO pubWarnVO = new PubWarnVO();
                    pubWarnVO.setWarnConment(warnVO.getStcd() + "的值：" + val + "已经超出阈值：74" );
                    pubWarnVO.setStcd(warnVO.getStcd());
                    pubWarnVO.setTime(warnVO.getTime());
                    exDataNum++;
                    list.add(pubWarnVO);
                }

            }
            pointCount.setWarnVOList(list);
            pointCount.setAnomalyNum(exDataNum);
        } else {
            List<PubSectionWarnVO> sectionList = pubPointAllDAO.getSectionStutasByType(params);

            if (CollUtil.isEmpty(sectionList)) {
                pointCount.setAnomalyNum(0);
            }

            int exDataNum = 0;

            Map<String, PubValVO> collect = upLowThresholdByPtcds.stream()
                    .collect(Collectors.toMap(PubValVO::getUnit, Function.identity()));
            List<PubWarnVO> list=new ArrayList<>();
            for (PubSectionWarnVO warnVO : sectionList) {
                if (collect.get(warnVO.getStcd()) != null) {
                    if (isAnomalousValue(collect.get(warnVO.getStcd()), warnVO)) {
                        PubWarnVO pubWarnVO = new PubWarnVO();
                        pubWarnVO.setStcd(warnVO.getStcd());
                        pubWarnVO.setTime(warnVO.getTime());
                        BigDecimal vals = Optional.ofNullable(warnVO.getVals())
                                .map(Object::toString)
                                .map(BigDecimal::new)
                                .orElse(BigDecimal.ZERO);
                        pubWarnVO.setWarnConment(warnVO.getStcd() + "的值：" + vals + "已经超出阈值：" + convertToBigDecimal(collect.get(warnVO.getStcd()).getUpperThreshold()));
                        list.add(pubWarnVO);
                        exDataNum++;
                    }
                }
            }
            pointCount.setWarnVOList(list);
          pointCount.setAnomalyNum(exDataNum);
        }

    }
    private String getValTypeMapping(String type, String dtvaltb) {
        Map<String, String> typeMapping = new HashMap<>();
        typeMapping.put("dsm_dfr_srhrds", "XHRDS");
        typeMapping.put("dsm_sst_st", "STN");
        typeMapping.put("dsm_spg_pzwl", "PZTBWL");
        typeMapping.put("dsm_sst_tm", "TM");
        typeMapping.put("dsm_sst_pr", "STS");

        if ("38".equals(type)) {
            typeMapping.put("st_rsvr_r", "W");
        } else {
            typeMapping.put("st_rsvr_r", "RZ");
        }
        typeMapping.put("st_pptn_r_day", "DRP");

        return typeMapping.get(dtvaltb);
    }

    private Map<String, Object> buildParamMap(String dtvaltb, String val, String ptcds) {
        Map<String, Object> params = new HashMap<>();
        params.put("val", val);
        params.put("dtvaltb", dtvaltb);
        params.put("time", (dtvaltb.equals("st_pptn_r_day") || dtvaltb.equals("st_rsvr_r")) ? "TM" : "MSTM");
        params.put("tcd", (dtvaltb.equals("st_pptn_r_day") || dtvaltb.equals("st_rsvr_r")) ? "STCD" : "MPCD");
        params.put("list", Arrays.asList(ptcds.split(",")));
        return params;
    }

    private boolean isAnomalousValue(PubValVO valVO, PubSectionWarnVO warnVO) {
        if (Objects.isNull(valVO)) return true;

        BigDecimal max = convertToBigDecimal(valVO.getUpperThreshold());
        BigDecimal min = convertToBigDecimal(valVO.getLowerThreshold());
        BigDecimal val = Optional.ofNullable(warnVO.getVals())
                .map(Object::toString)
                .map(BigDecimal::new)
                .orElse(BigDecimal.ZERO);

        return val.compareTo(max) > 0;
    }

    private BigDecimal convertToBigDecimal(Object value) {
        if (value == null) {
            return BigDecimal.ZERO;
        }
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        if (value instanceof Number) {
            return BigDecimal.valueOf(((Number) value).doubleValue());
        }
        try {
            return new BigDecimal(value.toString());
        } catch (NumberFormatException e) {
            return BigDecimal.ZERO;
        }
    }
    public List<PttnSectionVO> getPointType() {
        return pubPointAllDAO.getPointType();
    }

    @Override
    public List<PubSectionWarnVO> getPubPointHistoryData(Integer stationType, Integer timeType, String dataTime) {
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(dataTime)) {
            dataTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        }
        List<PubSectionWarnVO> list = new ArrayList<>();
        //判断站点类型
        //水位的 日数据取最高的， 月、年取平均值
        if (stationType.equals(15)) {
            list = pubPointAllDAO.getWaterLevelPointHistoryData(timeType, dataTime, stationType);
//            list.parallelStream().forEach(vo -> {
//                if ("10003".equals(vo.getStcd())) {
//                    vo.setVals(new BigDecimal(0));
//                }
//            });
            //雨量站
        } else if (stationType.equals(13)) {
            list = pubPointAllDAO.getRainfallPointHistoryData(timeType, dataTime, stationType);
        }
        list.forEach(r -> {
            if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(r.getPointTypeName())) {
                r.setStationName(r.getStationName() + "-" + r.getPointTypeName());
            }
        });
        return list;
    }


    @Override
    public List<PubSectionWarnVO> getSectionStutasByType(Integer type, boolean showAllSection) {
        List<PttnSectionVO> sectionByType = this.getSectionByType(type);
        String unitByStationType = pubPointAllDAO.getUnitByStationType(type);
        Map<String, PttnSectionVO> sectionMap = sectionByType.stream()
                .collect(Collectors.toMap(PttnSectionVO::getSubPtcd, Function.identity(), (existing, replacement) -> existing));
//        List<String> mpcdList = sectionByType.stream()
//                .map(PttnSectionVO::getPtcd)
//                .collect(Collectors.toList());

        List<PubSectionWarnVO> list = new ArrayList<>();
        String dtvaltb = pubPointAllDAO.getDtvaltbc(type);

        Map<String, String> typeMapping = new HashMap<>();
        typeMapping.put("dsm_dfr_srhrds", "XHRDS");
        typeMapping.put("dsm_sst_st", "STN");
        typeMapping.put("dsm_spg_pzwl", "PZTBWL");
        typeMapping.put("dsm_sst_tm", "TM");
        typeMapping.put("dsm_sst_pr", "STS");
        if (type.equals(38)) {
            //查询库容数据
            typeMapping.put("st_rsvr_r", "W");
        } else {
            typeMapping.put("st_rsvr_r", "RZ");
        }

        typeMapping.put("st_pptn_r_day", "DRP");
        if (type.equals(16) || "weatherdata".equals(dtvaltb)) {
            return  null;
        } else if (typeMapping.containsKey(dtvaltb)) {
            Map<String, Object> params = new HashMap<>();
            params.put("val", typeMapping.get(dtvaltb));
            // 动态值
            if (dtvaltb.equals("st_pptn_r_day")){
                dtvaltb="st_pptn_r";
            }
            params.put("dtvaltb", dtvaltb);

            if (dtvaltb.equals("st_pptn_r") || dtvaltb.equals("st_rsvr_r")) {
                params.put("time", "TM");
                params.put("tcd", "STCD");
            } else {
                params.put("time", "MSTM");
                params.put("tcd", "MPCD");
            }
            params.put("list", sectionMap.keySet());
            if (dtvaltb.equals("st_pptn_r")){
                list = pubPointAllDAO.geDrpByType();
            }else {
                list = pubPointAllDAO.getSectionStutasByType(params);
            }

        }


        dtvaltb =dtvaltb.equals("st_pptn_r") ?  "st_pptn_r_day" : dtvaltb;
        String finalDtvaltb1 = dtvaltb;
        list.forEach(item -> {
            PttnSectionVO pttnSectionVO = sectionMap.get(item.getStcd());
            if (!Objects.isNull(pttnSectionVO)) {
                item.setLatitude(pttnSectionVO.getLatitude());
                item.setLongitude(pttnSectionVO.getLongitude());
                item.setElevation(pttnSectionVO.getElevation());
                item.setStationName(pttnSectionVO.getName());
                item.setStcd(item.getStcd());
            }
            if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(unitByStationType)) {
                item.setDataUnit(unitByStationType);
            }

            Map<String, BigDecimal> limit = pubPointAllDAO.getStatus(item.getStcd());

            LambdaQueryWrapper<PubPointAllDO> wrapper = new LambdaQueryWrapper<PubPointAllDO>().eq(PubPointAllDO::getPtcd, item.getStcd()).eq(PubPointAllDO::getDtvaltb, finalDtvaltb1);
            PubPointAllDO pointAllDO = this.getOne(wrapper);
            item.setPoiStatus(pointAllDO.getState());
            if (limit != null) {
                Object maxValue = limit.get("max");
                Object minValue = limit.get("min");

                BigDecimal max = (maxValue instanceof Number) ? new BigDecimal(maxValue.toString()) : BigDecimal.ZERO;
                BigDecimal min = (minValue instanceof Number) ? new BigDecimal(minValue.toString()) : BigDecimal.ZERO;
                if (max != null && min != null) {
                    try {
                        BigDecimal vals = item.getVals() == null ? BigDecimal.ZERO : new BigDecimal(item.getVals().toString());
                        if (vals.compareTo(max) > 0 || vals.compareTo(min) < 0) {
                            item.setStatus(0);  // 超出范围
                        } else {
                            item.setStatus(1);  // 在范围内
                        }
                    } catch (NumberFormatException e) {
                        item.setStatus(0);
                    }
                } else {
                    item.setStatus(0);
                }
            } else {
                item.setStatus(0);
            }
        });

        if (showAllSection) {
            for (PttnSectionVO pttnSectionVO : sectionByType) {
                if (list.stream().filter(item -> item.getStcd().equals(pttnSectionVO.getPtcd())).count() < 1) {
                    PubSectionWarnVO pubSectionWarnVO = new PubSectionWarnVO();
                    pubSectionWarnVO.setStcd(pttnSectionVO.getPtcd());
                    pubSectionWarnVO.setLatitude(pttnSectionVO.getLatitude());
                    pubSectionWarnVO.setLongitude(pttnSectionVO.getLongitude());
                    pubSectionWarnVO.setElevation(pttnSectionVO.getElevation());
                    pubSectionWarnVO.setStationName(pttnSectionVO.getName());
                    list.add(pubSectionWarnVO);
                }
            }
        }
        return list;


    }

    @Override
    public List<WaterQualityVO> getWaterQualityList() {
        return pubPointAllDAO.getWaterQualityList();
    }

    @Override
    public List<OtherPptnPointVO> getOthetrPptnPoint(Integer type) {
        return pubPointAllDAO.getOthetrPptnPoint(type);
    }

    @Override
    public List<OtherPptnDateVO> getOhetrPptnDate(String stcd, String startTime, String endTime,Integer type,Integer code) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        if (startTime == null && endTime == null) {
            LocalDateTime now = LocalDateTime.now();
            endTime = now.format(formatter);
            startTime = now.minus(1, ChronoUnit.MONTHS).format(formatter);
        } else if (startTime == null) {
            // 如果只有 startTime 为 null，基于 endTime 计算 startTime
            LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
            startTime = endDateTime.minus(1, ChronoUnit.MONTHS).format(formatter);
        } else if (endTime == null) {
            // 如果只有 endTime 为 null，设置为当前时间
            endTime = LocalDateTime.now().format(formatter);
        }

        if (code==1){
            return pubPointAllDAO.getOhetrPptnDate(stcd,startTime,endTime,type);
        }
        if (code==2){
            return pubPointAllDAO.getOhetrRsvrDate(stcd,startTime,endTime,type);
        }
   return new ArrayList<>();
    }

    @Override
    public List<PubSectionWarnVO> getOhetrPptnLastDate(Integer type,Integer code) {
        if (code ==1){
            return pubPointAllDAO.getOhetrPptnLastDate(type,code);
        }
        if (code==2){
            return pubPointAllDAO.getOhetrRsvrLastDate(type,code);
        }
        return new ArrayList<>();
    }

    @Override
    public List<PttnSectionVO> getElectronicCrawl() {
        return pubPointAllDAO.getElectronicCrawl();
    }

    public List<PttnSectionVO> getSectionByType(Integer type) {

        List<PttnSectionVO> ptcdList = pubPointAllDAO.selectListBype(type);
        if (CollUtil.isNotEmpty(ptcdList)) {
            ptcdList.forEach(r -> {
                r.setPtcd(r.getPtcd().replace("_2", ""));
                r.setSubPtcd(r.getSubPtcd().replace("_2", ""));
                if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(r.getPointTypeName())) {
                    r.setName(r.getName() + "-" + r.getPointTypeName());
                }
            });
        }


        return ptcdList;
    }

    @Override
    public List<OtherPptnPointDataVO> getOhetrPptnPointDataList(Integer type,
                                                                String stcd,
                                                                String startTime,
                                                                String endTime) {
       //如果开始结束时间为null 默认取一个月数据
        if (startTime == null || endTime == null) {
            // 获取当前时间
            LocalDateTime now = LocalDateTime.now();
            // 默认结束时间为当前时间
            LocalDateTime defaultEndTime = now;
            // 默认开始时间为一个月前
            LocalDateTime defaultStartTime = now.minusMonths(1);

            // 转换为字符串格式（根据您的需求调整格式）
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

            if (startTime == null) {
                startTime = defaultStartTime.format(formatter);
            }
            if (endTime == null) {
                endTime = defaultEndTime.format(formatter);
            }
        }

        return pubPointAllDAO.getOhetrPptnPointDataList(type,stcd,startTime,endTime);
    }

    @Override
    public String getWaterFile() {
        return pubPointAllDAO.getWaterFile(getNowDateNew().getRz());
    }
}
